package cn.bonoon.kernel.descriptors.impl;

import java.lang.reflect.Field;

import cn.bonoon.kernel.annotations.QueryJoin;
import cn.bonoon.kernel.annotations.ResetProperty;
import cn.bonoon.kernel.annotations.condition.ConditionField;
import cn.bonoon.kernel.annotations.condition.ConditionWith;
import cn.bonoon.kernel.descriptors.QueryDescriptor;
import cn.bonoon.kernel.descriptors.QueryPropertyAccessor;
import cn.bonoon.kernel.util.StringHelper;

/**
 * 查询条件的描述器
 * 
 * @author jackson
 * 
 */
public final class QueryPropertyAccessorImpl extends MappablePropertyAccessor<QueryPropertyAccessor, QueryDescriptorImpl> implements QueryPropertyAccessor{

	private QueryPropertyAccessor next;
	private String nextProperty;
	private ConditionWith with;
	private final QueryJoin[] joins;
	private final String propertyName;

	public QueryPropertyAccessor next(QueryPropertyAccessor next) {
		this.next = next;
		return this.next;
	}

	public QueryPropertyAccessor next() {
		return this.next;
	}

	public boolean hasNext() {
		return null != next;
	}
	
	@Override
	public ResetProperty getPropertyReseter() {
		return classDescriptor.getPropertyReseter(propertyName);
	}

	public boolean isWith() {
		return null != with;
	}

	public QueryPropertyAccessorImpl(QueryDescriptorImpl queryDescriptorImpl, Field field) {
		super(queryDescriptorImpl, field);
		with = field.getAnnotation(ConditionWith.class);
		if (null != with) {
			nextProperty = with.value();
		}
		

		ConditionField cf = field.getAnnotation(ConditionField.class);
		String propertyName;
		if(null != cf){//不去前缀处理
			joins = cf.joins();
			propertyName = cf.value();
			if(propertyName.isEmpty() || ".".equals(propertyName)){
				propertyName = internalName(queryDescriptorImpl, field);
			}else if(propertyName.startsWith(".")){
				propertyName = internalName(queryDescriptorImpl, field) + propertyName;
			}else if(propertyName.endsWith(".")){
				propertyName += internalName(queryDescriptorImpl, field);
			}
		}else{
			joins = null;
			propertyName = internalName(queryDescriptorImpl, field);
		}
		this.propertyName = propertyName;
	}

	String internalName(QueryDescriptorImpl queryDescriptorImpl, Field field) {
		String propertyName;
		propertyName = field.getName();
		//去前缀处理
		String pv = queryDescriptorImpl.getPrefix();
		if (StringHelper.isNotEmpty(pv) && propertyName.startsWith(pv)) {
			int sp = pv.length(), len = propertyName.length() - sp;
			if(len > 0){
				char[] chs = propertyName.toCharArray();
				chs[sp] = Character.toLowerCase(chs[sp]);
				propertyName = new String(chs, sp, len);
			}
		}
		return propertyName;
	}
	
	@Override
	public String getNextProperty() {
		return nextProperty;
	}
	
	@Override
	public String queryProperty(){
		return propertyName;
	}
	
	@Override
	public QueryJoin[] getJoins() {
		return joins;
	}

	@Override
	public QueryDescriptor getDescriptor() {
		return classDescriptor;
	}
}
